/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.ufrn.dimap.projetodetalhadodesoftware.chatrmi.controller;

import br.ufrn.dimap.projetodetalhadodesoftware.chatrmi.model.actor.ChatModel;
import br.ufrn.dimap.projetodetalhadodesoftware.chatrmi.model.actor.ClientModel;
import br.ufrn.dimap.projetodetalhadodesoftware.chatrmi.controller.exception.MaximumNumberExceededException;
import br.ufrn.dimap.projetodetalhadodesoftware.chatrmi.controller.exception.ObjectNotFoundExeption;
import br.ufrn.dimap.projetodetalhadodesoftware.chatrmi.view.ChatView;
import br.ufrn.dimap.projetodetalhadodesoftware.chatrmi.model.observer.Observer;
import br.ufrn.dimap.projetodetalhadodesoftware.chatrmi.model.observer.Subject;
import br.ufrn.dimap.projetodetalhadodesoftware.chatrmi.model.reference.ManagerReference;
import br.ufrn.dimap.projetodetalhadodesoftware.chatrmi.model.register.Register;
import java.io.Serializable;
import java.net.MalformedURLException;
import java.rmi.NotBoundException;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import br.ufrn.dimap.projetodetalhadodesoftware.chatrmi.model.util.Message;

/**
 *
 * @author jorge
 */
public class ChatController extends Register implements Serializable, ChatControllerInterface, ChatInterface, Subject {

    private ManagerReference managerReference;
    private ServerInterface server;
    private ChatModel chatModel;
    private ChatView guiChat;

    public ChatController(ChatModel chatModel, ChatView guiChat, String ip, int port) throws RemoteException, NotBoundException, MalformedURLException, ObjectNotFoundExeption {
        super("rmi://" + ip + ":" + port + "/" + chatModel.getTheme(), port);
        managerReference = ManagerReference.getInstance();
        server = (ServerInterface) managerReference.getReference(managerReference.SERVER, ServerControler.address);
        this.chatModel = chatModel;
        this.guiChat = guiChat;
    }

    public void connectToServer() throws RemoteException, NotBoundException, MalformedURLException {

        server.Attach(this);

        guiChat.displayMessage("Chat conectado com sucesso!!");

    }

    public void MessageFromClient(String message) throws RemoteException {

        Message mes = new Message();
        mes.setCode(Message.MESSAGE);
        mes.setContent(message);

        Notify(mes);
    }

    public String getTheme() throws RemoteException {
        return chatModel.getTheme();
    }

    public int getNumberClients() throws RemoteException {
        return chatModel.getClientsList().size();
    }

    public List<ClientInterface> getClients() throws RemoteException {
        return chatModel.getClientsList();
    }

    public int getId() throws RemoteException {
        return chatModel.getId();
    }

    public void Notify(Message message) throws RemoteException {
        for (int i = 0; i < chatModel.getClientsList().size(); i++) {
            chatModel.getClientsList().get(i).update(message);
        }
    }

    public void Attach(Remote o) throws RemoteException {


        if (chatModel.getClientsList().size() <= chatModel.getNumMaxOfClients()) {
            try {
                ClientInterface clientInterface = (ClientInterface) o;
                clientInterface = (ClientInterface) managerReference.getReference(managerReference.CLIENT, clientInterface.getURL());
                chatModel.getClientsList().add(clientInterface);

                Message message = new Message();
                message.setCode(Message.UPDATE_NUM_CLIENTS);
                message.setContent(chatModel.getClientsList().size());

                Notify(message);

                MessageFromClient(clientInterface.getName()+" is available\n");


            } catch (NotBoundException ex) {
                Logger.getLogger(ChatController.class.getName()).log(Level.SEVERE, null, ex);
            } catch (MalformedURLException ex) {
                Logger.getLogger(ChatController.class.getName()).log(Level.SEVERE, null, ex);
            } catch (ObjectNotFoundExeption ex) {
                Logger.getLogger(ChatController.class.getName()).log(Level.SEVERE, null, ex);
            }
        } else {
            try {
                throw new MaximumNumberExceededException();
            } catch (MaximumNumberExceededException ex) {
                Logger.getLogger(ChatController.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

    }

    public void Detach(Remote o) throws RemoteException {
        ClientInterface client =  (ClientInterface) o;
        chatModel.getClientsList().remove(client);

        Message message = new Message();
        message.setCode(Message.UPDATE_NUM_CLIENTS);
        message.setContent(chatModel.getClientsList().size());

        Notify(message);

        MessageFromClient(client.getName() + " is unavailable\n");

    }

    public void setId(int id) throws RemoteException {
        chatModel.setId(id);
    }

    public String getURL() throws RemoteException {
        return super.getUrl();
    }

    public void createRegister() throws RemoteException, MalformedURLException {
        super.register();
    }
}
